package com.min.netty.file.handler;

import com.min.netty.file.MinFileServer;
import com.min.netty.file.constant.Constant;
import com.min.netty.file.constant.TransferFile;
import io.netty.channel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.RandomAccessFile;
import java.net.InetSocketAddress;
import java.nio.file.Path;
import java.nio.file.Paths;

public class MinFileServerHandler extends ChannelInboundHandlerAdapter {
    private static final Logger LOGGER = LoggerFactory.getLogger(MinFileServer.class);
    private static final String PATH = "d:\\temp2";

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        if (LOGGER.isDebugEnabled()) {
            InetSocketAddress remote = (InetSocketAddress) ctx.channel().remoteAddress();
            LOGGER.debug("====建立连接，IP={}，port={}",
                    remote.getAddress().getHostAddress(), remote.getPort());
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        if (LOGGER.isDebugEnabled()) {
            InetSocketAddress remote = (InetSocketAddress) ctx.channel().remoteAddress();
            LOGGER.debug("====断开连接，IP={}，port={}",
                    remote.getAddress().getHostAddress(), remote.getPort());
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof String) {

            ctx.writeAndFlush(Constant.TRANSMIT_START);
            // 秒传功能还没有开发出来
//      ctx.writeAndFlush(Constant.TRANSMIT_MD5_EXISTS);
//      LOGGER.info("秒传文件：md5 = {}", msg);
        } else if (msg instanceof TransferFile) {
            TransferFile file = (TransferFile) msg;
            int start = file.getStarPos();
            int byteRead = file.getEndPos();
            byte[] bytes = file.getBytes();
            Path path = Paths.get(PATH, file.getFile().getName() + file.getExt());
            // 以读写方式创建文件
            RandomAccessFile randomAccessFile = new RandomAccessFile(path.toFile(), Constant.FILE_WRITE);
            randomAccessFile.seek(start);
            randomAccessFile.write(bytes);
            if (byteRead > 0) {
                // 将下一段的起始点发给客户端
                ctx.writeAndFlush(start + byteRead).addListener(new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture future) throws Exception {
                        randomAccessFile.close();
                        if (Constant.SEND_SIZE != byteRead) {
                            // 当读的字节数小于单次发送数量，表示文件已全接收
                            future.channel().close();
                            if (LOGGER.isDebugEnabled()) {
                                InetSocketAddress remote = (InetSocketAddress) ctx.channel().remoteAddress();
                                LOGGER.debug("====文件接收完毕，IP={}，port={}，保存文件={}",
                                        remote.getAddress().getHostAddress(), remote.getPort(), path.toString());
                            }
                        }
                    }
                });
            } else {
                ctx.close();
            }
        } else {
            ctx.channel().writeAndFlush(Constant.SEND_CORRECT_DATA)
                    .addListener(ChannelFutureListener.CLOSE);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        ctx.close();
        cause.printStackTrace();
    }
}
